import { ComponentClass } from 'react'
import Taro, { Component, Events } from '@tarojs/taro'
import { View, Text } from '@tarojs/components'

import { noConsole } from '../../config';
import Constants  from '../../config/constants'

type PageStateProps = {}

type PageDispatchProps = {}

export type PageOwnProps = {
  // 分页加载的数据
  dataArray: Array<any>,
  // 数据总条数
  total: number,
  // 分页数据数
  pageSize: number,
  // 没有搜索结果的提示语
  inputNoneResultTips?: string,
  // 没有搜索到更多结果的提示语
  inputNoMoreResultTips?: string,
  // 加载中的标志位  true:表示加载中
  loading: boolean,
  // 事件名后缀
  eventSuffix: string,
}

type PageState = {
  // 没有搜索到结果的标志位  true:表示没有搜索到数据
  noneResult: boolean,
  // 没有更多搜索结果的提示语
  noneResultTips: string,
  // 已加载的数据缓存
  allDatas: any[],
  // 下一页的页数
  nextPage: number,
}

type IProps = PageStateProps & PageDispatchProps & PageOwnProps

interface Pagination {
  props: IProps;
  state: PageState;
}

/**
 * 分页组件
 */
class Pagination extends Component {

  constructor(props) {
    super(props);

    this.state = {
      noneResult: this.props.total === 0,
      noneResultTips: this.props.inputNoneResultTips || '',
      allDatas: this.props.dataArray,
      nextPage: 0,
    }
  }

  public static defaultProps: PageOwnProps = {
    dataArray: [],
    total: 0,
    pageSize: 10,
    loading: false,
    inputNoneResultTips: '没有搜索到数据',
    inputNoMoreResultTips: '没有更多数据了',
    eventSuffix: '',    
  };
  
  componentDidMount() {
    this.initEventHandler()
  }

  componentWillReceiveProps(nextProps) {
    if (!noConsole) {
      // console.log('Pagination component, componentWillReceiveProps', this.props, nextProps)

      // 判断输入参数是否发生变化，有变化则重新计算
      const curProps = {
        dataArray: this.props.dataArray,
        total: this.props.total,
        pageSize: this.props.pageSize,
      }
      const updateProps = {
        dataArray: nextProps.dataArray,
        total: nextProps.total,
        pageSize: nextProps.pageSize,
      }
      if (JSON.stringify(curProps) !== JSON.stringify(updateProps)) {
        // 计算分页信息
        this.updatePageInfo(updateProps.dataArray, updateProps.total)
        // 发射分页信息事件
        // this._sendPageDataEvent()
      }
    }
  }

  componentWillUnmount() { 
    this.removeEventHandler()
  }

  componentDidShow() { }

  componentDidHide() { }

  render() {
    return (<View>
        {/* <Text>pagination 高阶组件 total = {this.props.total}</Text> */}
      </View>)
  }

  /**
   * 更新分页信息
   * @param datas 新加载的数据数组
   * @param total 数据总数
   */
  updatePageInfo(datas: any[], total: number) {
    const allDatas = this._getMoreData(datas);
    const totalInfo = this._getTotalAndResultTips(total, allDatas);
    const nextPage = this._getNextPage(allDatas.length, this.props.pageSize);

    this.setState(Object.assign(this.state, {
      allDatas: allDatas,
      ...totalInfo,
      nextPage,
    }), () => {
      // 必须在这里发射
      this._sendPageDataEvent()
    });
  }

  /**
   * 初始化消息中心监听
   */
  initEventHandler() {
    const that = this
   
    Taro.eventCenter.on(`${Constants.PAGINATION_PAGE_RELOAD_EVENT}${this.props.eventSuffix}`, () => {
      console.log('分页组件 接收到 PAGINATION_PAGE_RELOAD_EVENT')
      that._resetPageData()
      that._sendPageDataEvent()
    })
  }

  removeEventHandler() {

  }

  /**
   * 发射分页信息更新事件
   */
  _sendPageDataEvent() {
    const that = this
    Taro.eventCenter.trigger(`${Constants.PAGINATION_PAGE_UPDATE_EVENT}${this.props.eventSuffix}`, {
      nextPage: that.state.nextPage,
      dataArray: that.state.allDatas,
      noneResult: that.state.noneResult,
      noneResultTips: that.state.noneResultTips,
    })
  }

  /**
   * 重置分页参数
   */
  _resetPageData() {
    const resetPage = {
      allDatas: [],
      nextPage: 0,
    }
    this.setState(Object.assign(this.state, resetPage))
  }

  /**
   * 把新加载的数据放入缓存
   * 返回新的缓存数据
   * @param dataArray 新加载的数据
   */  
  _getMoreData(dataArray: any[]): any[] {
    
    let tempArray = this.state.allDatas

    if (dataArray.length > 0) {
      tempArray = tempArray.concat(dataArray);
    }

    return tempArray
  }

  /**
   * 根据 total 与 allDatas 判断是否还有更多数据
   * @param total 数据总数
   * @param allDatas 已加载的所有数据
   */
  _getTotalAndResultTips(total: number, allDatas: any[]): ({
    total: number,
    noneResult: boolean,
    noneResultTips: string,
  }) {

    const result = {
      total,
      noneResult: false,
      noneResultTips: '',
    }

    if (total === 0) {
      result.noneResult = true;
      result.noneResultTips = this.props.inputNoneResultTips || '';
    } else {
      if (allDatas.length >= total) {
        // 没有更多数据的话，设置noneResult为true
        result.noneResult = true;
        result.noneResultTips = this.props.inputNoMoreResultTips || '';
      } 
    }

    return result;
  }

  /**
   * 计算下一页数据的页数
   * @param allDataLength  现在所有数据的数量
   * @param pageSize 
   */
  _getNextPage(allDataLength: number, pageSize: number = this.props.pageSize) {
    return allDataLength / pageSize
  }
}

export default Pagination as ComponentClass<PageOwnProps, PageState>
